<?php
/**
 * Module Videos
 *
 * @author develx
 */
class Videos extends Module {
    protected $name = 'Videos';
    protected $administrable = true;
    protected $version = '2010-08-18';
    protected $details = array('dependencies' => array(),
            'observes' => array('Videos'));

    const CATEGORIES = 'videosCategories';
    const VIDEOS = 'videos';
    const TAGS = 'videosTags';

    protected $categoriesTable = array('id' => 'iPN+', 'title' => 'sN',
            'description' => 'T');
    protected $videosTable = array('id' => 'iPN+', 'source' => "v'4096'N",
            'category' => 'iNI', 'title' => "v'1024'", 'description' => 'T',
            'views' => 'iN', 'server' => 's', 'vidID' => 's', 'flashVars' =>
            "v'8192'", 'thumbnail' => 'i', 'added' => 'iN', 'featured' =>
            'iNI');
    protected $tagsTable = array('video' => 'iNI', 'tag' => "v'255'I");

    protected $categoryRecord = array('table' => self::CATEGORIES, 'data' =>
            array());
    protected $videoRecord = array('table' => self::VIDEOS, 'data' => array());
    protected $tagRecord = array('tables' => self::TAGS, 'data' => array());

    protected $filesRoot = 4;

    public function __construct(DBAPI $dbapi, RecordList $recordList) {
        parent::__construct($dbapi, $recordList);
        $this->categoryRecord['properties'] = $this->categoriesTable;
        $this->videoRecord['properties'] = $this->videosTable;
        $this->tagRecord['properties'] = $this->tagsTable;
    }

    public function install() {
        Modules::getModule('Users')->registerRights($this->getName(),
                $this->getRights());
        return $this->dbdriver->createTable(self::CATEGORIES,
                $this->categoriesTable) &&
                $this->dbdriver->createTable(self::VIDEOS,
                $this->videosTable) &&
                $this->dbdriver->createTable(self::TAGS, $this->tagsTable);
    }

    public function uninstall() {
        return $this->dbdriver->dropTable(self::CATEGORIES) &&
                $this->dbdriver->dropTable(self::VIDEOS) &&
                $this->dbdriver->dropTable(self::TAGS);
    }

    public function onAddCategory(&$details, $source) {
        if (!$this->hasRights('add category')) {
            return;
        }
        $category = $this->fillRecord($this->categoryRecord, $details);
        $this->dbapi->save($category);
        Kernel::setRedirect($this->getLink('categories/'));
    }

    public function onEditCategory(&$details, $source) {
        if (!$this->hasRights('edit category')) {
            return;
        }
        Kernel::setRedirect($this->getLink('categories/'));
        $category = $this->fillRecord($this->categoryRecord, $details);
        $this->dbapi->update($category);
    }

    public function onDeleteCategory(&$details, $source) {
        Kernel::setRedirect($this->getLink('categories/'));
        if (!$this->hasRights('delete category')) {
            return;
        }
        $this->dbdriver->delete(self::CATEGORIES, '`id` = ' . (int) $details);
    }

    public function onAddVideo(&$details, $source) {
        if (!$this->hasRights('add video')) {
            return;
        }
        $server = preg_replace('/^http:\\/\\/(www[.])?((\w|[.])*)\\/.*$/',
                '$2', $details['sourceURL']);
        $method = "addFrom" . str_replace('.', '_', ucfirst($server));
        $this->{$method}($details['sourceURL'], isset($details['featured']),
                $details['category']);
    }

    public function onDeleteVideo(&$details, $source) {
        Kernel::setRedirect($this->getLink());
        if (!$this->hasRights('delete video')) {
            return;
        }
        $this->dbdriver->delete(self::VIDEOS, '`id` = ' . (int) $details);
    }

    public function onEditVideo(&$details, $source) {
        if (!$this->hasRights('edit video')) {
            return;
        }
        $video = $this->fillRecord($this->videoRecord, $details);
        $this->dbapi->refresh($video);
        $video = $this->fillRecord($video, $details);
        $video['data']['source'] = $details['sourceURL'];
        $video['data']['featured'] = isset($details['featured']) ? 1 : 0;
        $this->dbapi->update($video);
    }

    public function initDisplayAdminAddCategory() {
        $this->js(Config::WEB_DIR . '/utils/tiny_mce/tiny_mce.js', false);
        $this->js('/wysiwyg.js');
    }

    public function initDisplayAdminEditCategory() {
        $this->initDisplayAdminAddCategory();
    }

    public function displayPublicBrowse($order = 'newest') {
        $cols = array('id', 'title', 'description', 'views', 'thumbnail');
        $order = array($order == 'newest' ? '!id' : '!views');
        $videos = &$this->dbdriver->select(self::VIDEOS, $cols, '', $order);
        foreach ($videos as &$video) {
            $video['comments'] = Modules::getModule('Comments')->
                    getCommentsCountOnUrl('videa/play/' .
                    Kernel::createUrl($video['title']) . '-' . $video['id']);
            $video['link'] = $this->getLink("play/" .
                    Kernel::createUrl($video['title']) . '-' . $video['id'] .
                    '/');
        }
        $params = array('videos' => $videos, 'category' => array('title' =>
                $this->lang('browseTitle')), 'newestLink' =>
                $this->getLink('browse/newest/'), 'viewedLink' =>
                $this->getLink('browse/most-viewed/'), 'featured' =>
                $this->getRandomFeatured());
        $this->template('category', $params);
    }

    public function displayPublicPlay($id) {
        $video = $this->videoRecord;
        $video['data']['id'] = (int) substr($id, strrpos($id, '-') + 1);
        $this->dbapi->refresh($video);
        $video['data']['views']++;
        $this->dbapi->update($video);
        $this->template('public-stream.cz', $video['data']);
    }

    public function displayPublicCategory($category, $order = 'newest') {
        $cId = (int) substr($category, strrpos($category, '-') + 1);
        $category = $this->categoryRecord;
        $category['data']['id'] = $cId;
        $this->dbapi->refresh($category);
        $cols = array('id', 'title', 'description', 'views', 'thumbnail');
        $order = array($order == 'newest' ? '!id' : '!views');
        $videos = &$this->dbdriver->select(self::VIDEOS, $cols,
                '`category` = ' . $cId, $order);
        foreach ($videos as &$video) {
            $video['comments'] = Modules::getModule('Comments')->
                    getCommentsCountOnUrl('videa/play/' .
                    Kernel::createUrl($video['title']) . '-' . $video['id']);
            $video['link'] = $this->getLink("play/" .
                    Kernel::createUrl($video['title']) . '-' . $video['id'] .
                    '/');
        }
        $params = array('videos' => $videos,
                'category' => &$category['data'], 'newestLink' =>
                $this->getLink('category/' .
                Kernel::createUrl($category['data']['title']) . '-' .
                $category['data']['id'] . '/newest/'), 'viewedLink' =>
                $this->getLink('category/' .
                Kernel::createUrl($category['data']['title']) . '-' .
                $category['data']['id'] . '/most-viewed/'), 'featured' =>
                $this->getRandomFeatured());
        $this->template('category', $params);
    }

    public function displayAdminEdit($id) {
        if (!$this->hasRights('edit video')) {
            return;
        }
        $video = $this->videoRecord;
        $video['data']['id'] = (int) $id;
        $this->dbapi->refresh($video);
        $form = $this->createEditForm('editVideo', $video);
        array_splice($form['items'], 9, 2);
        $form['items'][9]['type'] = 'checkbox';
        $form['items'][9]['checked'] = $form['items'][9]['value'] == 1;
        $cols = array('id', 'title');
        $categoriesDB = &$this->dbdriver->select(self::CATEGORIES, $cols);
        $categories = array();
        foreach ($categoriesDB as &$category) {
            $categories[$category['id']] = $category['title'];
        }
        $form['items'][2]['type'] = 'select';
        $form['items'][2]['options'] = &$categories;
        $form['items'][2]['selected'] = $form['items'][2]['value'];
        $form['items'][1]['name'] = 'sourceURL';
        $this->displayForm($form);
    }

    public function displayAdminPlay($id) {
        $video = $this->videoRecord;
        $video['data']['id'] = (int) $id;
        $this->dbapi->refresh($video);
        $this->template('stream.cz', $video['data']);
    }

    public function displayAdminIndex() {
        $cols = array('id', 'title');
        $order = array('!id');
        $videos = &$this->dbdriver->select(self::VIDEOS, $cols, '', $order);
        foreach ($videos as &$video) {
            $video['play'] = $this->getLink("play/{$video['id']}/");
            $video['edit'] = $this->getLink("edit/{$video['id']}/");
            $video['delete'] = $this->getLink($video['id'], 'deleteVideo');
        }
        $params = array('videos' => &$videos);
        $this->template('videolist', $params);
    }

    public function displayAdminAddVideo() {
        if (!$this->hasRights('add video')) {
            return;
        }
        $cols = array('id', 'title');
        $categoriesDB = &$this->dbdriver->select(self::CATEGORIES, $cols);
        $categories = array();
        foreach ($categoriesDB as &$category) {
            $categories[$category['id']] = $category['title'];
        }
        $form = array('start' => 'addVideo', 'legend' => 'addVideoLegend',
                'submit' => 'create', 'items' => array());
        $form['items'][] = array('name' => 'sourceURL', 'label' => 'source',
                'value' => 'http://');
        $form['items'][] = array('name' => 'category', 'label' => 'category',
                'type' => 'select', 'options' => &$categories);
        $form['items'][] = array('name' => 'featured', 'label' => 'featured',
                'type' => 'checkbox', 'checked' => false);
        $this->prepareFormData($form);
        $params = array('form' => &$form);
        $this->template('form', $params);
    }

    public function displayAdminEditCategory($id) {
        if (!$this->hasRights('edit category')) {
            return;
        }
        $category = $this->categoryRecord;
        $category['data']['id'] = (int) $id;
        $this->dbapi->refresh($category);
        $form = $this->createEditForm('editCategory', $category);
        $form['items'][2]['type'] = 'textarea';
        $form['items'][2]['cols'] = 80;
        $form['items'][2]['rows'] = 6;
        $this->displayForm($form);
    }

    public function displayAdminCategories() {
        $cols = array('id', 'title');
        $categories = &$this->dbdriver->select(self::CATEGORIES, $cols);
        foreach ($categories as &$category) {
            $category['edit'] =
                    $this->getLink("edit-category/{$category['id']}/");
            $category['delete'] = $this->getLink($category['id'],
                    'deleteCategory');
        }
        $params = array('categories' => &$categories);
        $this->template('categories', $params);
    }

    public function displayAdminAddCategory() {
        if (!$this->hasRights('add category')) {
            return;
        }
        $form = $this->createAddForm('addCategory', $this->categoriesTable);
        $form['items'][1]['type'] = 'textarea';
        $form['items'][1]['cols'] = 80;
        $form['items'][1]['rows'] = 6;
        $this->displayForm($form);
    }

    public function displayAdminSubmenu() {
        $menu = array(
            array('href' => '', 'label' => 'videosList'),
            array('href' => 'add-video/', 'label' => 'addVideo'),
            array('href' => 'categories/', 'label' => 'categories'),
            array('href' => 'add-category/', 'label' => 'addCategory')
        );
        $this->prepareMenu($menu);
        $params = array('menu' => &$menu);
        $this->template('submenu', $params);
    }

    public function addFromStream_cz($source, $featured, $category) {
        $page = file_get_contents($source);
        $id = preg_replace('/^.*\\/video\\/(\d+)-.*$/', '$1', $source);
        $title = explode('<title>', $page, 2);
        $title = explode('- Stream.cz', $title[1], 2);
        $title = trim($title[0]);
        $description = explode('<div id="video_popisek">', $page, 2);
        $description = explode('</div>', $description[1], 2);
        $description = trim($description[0]);
        $thumbnail = explode('<link rel="image_src" href="', $page, 2);
        $thumbnail = explode('"', $thumbnail[1]);
        $thumbnail = array($thumbnail[0]);
        $thumbnail = Modules::getModule('Files')->mirrorFiles($thumbnail,
                $this->filesRoot);
        $video = $this->videoRecord;
        $video['data'] = array(
            'source' => $source,
            'category' => $category,
            'title' => $title,
            'description' => $description,
            'views' => 0,
            'server' => 'stream.cz',
            'vidID' => $id,
            'flashVars' => '',
            'thumbnail' => $thumbnail[0]['data']['id'],
            'added' => time(),
            'featured' => $featured ? 1 : 0
        );
        $this->dbapi->save($video);
    }

    private function getRandomFeatured() {
        $cols = array('COUNT(*)');
        $count = &$this->dbdriver->select(self::VIDEOS, $cols,
                '`featured` = 1');
        if ($count[0]['COUNT(*)'] == 0) {
            return false;
        }
        $cols = array('id', 'title', 'description', 'thumbnail');
        $featured = &$this->dbdriver->select(self::VIDEOS, $cols,
                '`featured` = 1', $order, rand(0, $count[0]['COUNT(*)'] - 1),
                1);
        $featured[0]['link'] = $this->getLink("play/" .
                    Kernel::createUrl($featured[0]['title']) . '-' .
                    $featured[0]['id'] . '/');
        return $featured[0];
    }
}
?>
